﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using NSsh.Server.TransportLayer.State;
using System.IO;
using NSsh.Common.Packets;
using NSsh.Common.Tests;
using NSsh.Common;
using NSsh.Server.TransportLayer;
using Rhino.Mocks;
using NSsh.Common.Utility;

namespace NSsh.Server.Tests.TransportLayer.State
{
    [TestFixture]
    public class AbstractTransportStateFixture
    {
        private MockRepository _mockRepository;
        private ITransportLayerManager _manager;

        [SetUp]
        public void Setup()
        {
            _mockRepository = new MockRepository();
            _manager = _mockRepository.CreateMock<ITransportLayerManager>();

            Dependency.Clear();
            Dependency.RegisterInstance<ISecureRandom>("SecureRandom", new SecureRandom());
        }

        [Test]
        public void ShouldProcessPacket()
        {
            using (_mockRepository.Record())
            {
                Expect.Call(_manager.ReadPacket()).Return(new IgnorePacket());
            }

            using (_mockRepository.Playback())
            {
                AbstractTransportState abstractState = new TestAbstractTransportState();
                abstractState.ProcessPacket(_manager);
            }
        }

        [Test]
        public void ShouldFailForKexInit()
        {
            TestInvalidPacketForState(new KexInitPacket());
        }

        public void TestInvalidPacketForState(Packet packet)
        {
            using (_mockRepository.Record())
            {
                Expect.Call(_manager.ReadPacket()).Return(packet);
            }

            using (_mockRepository.Playback())
            {
                AbstractTransportState abstractState = new TestAbstractTransportState();

                Assert.That(new MethodInvoker(delegate
                {
                    abstractState.ProcessPacket(_manager);

                }), Throws.Exception<InvalidOperationException>());
            }
        }
    }

    class TestAbstractTransportState : AbstractTransportState
    {
        [CoverageExclude]
        public override void Process(ITransportLayerManager manager) { }
    }
}
